/*****************************************************************************
* File Name: trackpad.c
*
* Version: 1.0
*
* Description:
* This file contains functions related trackpad module implementation 
*
* Note:
*
*
* Owner: SKUV
*
* Related Document:
* Capsense CSD P4 component datasheet
*
* Hardware Dependency:
* Capsense_CSD_P4 PSoC Creator Component
*
* Code Tested With:
* 1. PSoC Creator 3.1 
* 2. ARM GCC 4.8.4
******************************************************************************
* Copyright (2015), Cypress Semiconductor Corporation.
******************************************************************************
* This software is owned by Cypress Semiconductor Corporation (Cypress) and is
* protected by and subject to worldwide patent protection (United States and
* foreign), United States copyright laws and international treaty provisions.
* Cypress hereby grants to licensee a personal, non-exclusive, non-transferable
* license to copy, use, modify, create derivative works of, and compile the
* Cypress Source Code and derivative works for the sole purpose of creating
* custom software in support of licensee product to be used only in conjunction
* with a Cypress integrated circuit as specified in the applicable agreement.
* Any reproduction, modification, translation, compilation, or representation of
* this software except as specified above is prohibited without the express
* written permission of Cypress.
*
* Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
* Cypress reserves the right to make changes without further notice to the
* materials described herein. Cypress does not assume any liability arising out
* of the application or use of any product or circuit described herein. Cypress
* does not authorize its products for use as critical components in life-support
* systems where a malfunction or failure may reasonably be expected to result in
* significant injury to the user. The inclusion of Cypress' product in a life-
* support systems application implies that the manufacturer assumes all risk of
* such use and in doing so indemnifies Cypress against all charges. Use may be
* limited by and subject to the applicable Cypress software license agreement.
*****************************************************************************/
#include "trackpad.h"
#include "visual_scop.h"
#include "simple_motion.h"

#ifndef DISABLE_TRACKPAD

uint32 numberOfFingers = 0;
uint32 prevnumberofFingers = 0;
bool customGestureEnabled = false;
bool prevClickGesture = false;
static bool isLowPowerMode = false;
static bool isScanInitiated = false;
static ReportType prevReportType = NO_REPORT;
uint8 gesture_code = 0;
CSD_Touchpad_POSITION_STRUCT fingerPosition[2];
static uint8 sensorToScan = 0;
uint8 sensorSignal[CSD_Touchpad_TOTAL_SENSOR_COUNT] = {0u};

static bool isRowScan;

uint8 trackpad_gesture_code = 0;
uint8 trackpad_send_nocode  = 0;

extern ReportType Trackpad_Gesture_Map(Report *report, uint32 gesture_code);
extern void Trackpad_Custom_Gesture_Detection(uint8 *gesture_code);
extern void Trackpad_Custom_Gesture_Init(void);
/*****************************************************************************
* Function Name: Trackpad_Init()
******************************************************************************
* Summary:
* This function is used to initialize trackpad module
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* Initialize the CSD component
*
* Side Effects:
* None
*
* Note:
* None
*****************************************************************************/
void Trackpad_Init(void)
{
#ifndef TOUCHPAD_TUNER    
    CSD_Touchpad_Start();
    Trackpad_Custom_Gesture_Init();
    CSD_Touchpad_InitializeEnabledBaselines();
#else
    CSD_Touchpad_TunerStart();

    for(;;)
    {
        Watch_Dog_Timer_Disable();
        CSD_Touchpad_TunerComm();
    }
#endif /* TOUCHPAD_TUNER */
}

/*****************************************************************************
* Function Name: Trackpad_Reset()
******************************************************************************
* Summary:
* This function is reset the trackpad module
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* ReInitialize the CSD component
*
* Side Effects:
* None
*
* Note:
* None
*****************************************************************************/
void Trackpad_Reset(void)
{
#ifndef DISABLE_TRACKPAD_SLEEP
    CSD_Touchpad_Wakeup();
#endif /* DISABLE_TRACKPAD_SLEEP */
	CSD_Touchpad_InitializeEnabledBaselines();
    CSD_Touchpad_ScanEnabledWidgets();
    while(CSD_Touchpad_IsBusy());
    CSD_Touchpad_UpdateEnabledBaselines();
#ifndef DISABLE_TRACKPAD_SLEEP
    CSD_Touchpad_SaveConfig();
    CSD_Touchpad_Sleep();
#endif /* DISABLE_TRACKPAD_SLEEP */
}

/*****************************************************************************
* Function Name: Trackpad_Start_Poll()
******************************************************************************
* Summary:
* This function is used to initiate trackpad scanning.
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* This function starts scans for all enabled widgets
*
* Side Effects:
* sensorToScan is updated
*
* Note:  
* Sequence of functions to be called by application for sucessful Trackpad Module scanning and 
* gesture decoding is as follows
* 1. Trackpad_Start_Poll()
* 2. Trackpad_IsComplete()
* 3. Trackpad_Poll()
*****************************************************************************/
void Trackpad_Start_Poll(void)
{
#ifndef DISABLE_TRACKPAD_SLEEP
    CSD_Touchpad_Wakeup();
#endif /* DISABLE_TRACKPAD_SLEEP */

   /* In low power mode, scan only 4 alternate column sensors */
    if(isLowPowerMode)
    {
        if(!isRowScan)
        {
            sensorToScan = CSD_Touchpad_SENSOR_TRACKPAD_COL1__TP ;
        }
        else
        {
            sensorToScan = CSD_Touchpad_SENSOR_TRACKPAD_ROW1__TP ;
        }
        CSD_Touchpad_ScanSensor(sensorToScan);
    }
    else
    {
        CSD_Touchpad_ScanEnabledWidgets();
    }
    isScanInitiated = true;
}

/*****************************************************************************
* Function Name: Trackpad_IsComplete()
******************************************************************************
* Summary:
* This function is used return status of trackpad scanning
*
* Parameters:
* None
*
* Return:
* Returns status of trackpad scanning
*
* Theory:
* This function polls for the status of trackpad scanning and returns the scanning status information
*
* Side Effects:
* sensorToScan is updated
*
* Note:  
* Sequence of functions to be called by application for successful trackpad module scanning and 
* gesture decoding is as follows
* 1. Trackpad_Start_Poll()
* 2. Trackpad_IsComplete()
* 3. Trackpad_Poll()
*****************************************************************************/
bool Trackpad_IsComplete(void)
{
    bool result = false;
    if(isLowPowerMode)
    {
        if(CSD_Touchpad_IsBusy() == 0)
        {
            if((!isRowScan && sensorToScan <= CSD_Touchpad_SENSOR_TRACKPAD_COL4__TP) || 
                (isRowScan && sensorToScan <= CSD_Touchpad_SENSOR_TRACKPAD_ROW4__TP))
            {
                sensorToScan += 2;
                CSD_Touchpad_ScanSensor(sensorToScan);
                result = false;
            }
            else
            {
                result = true;
            }
        }
        else
        {
            result = false;
        }
    }
    else
    {
        result = ((bool) CSD_Touchpad_IsBusy() == 0);
    }
    return result;
}

/*****************************************************************************
* Function Name: Trackpad_Poll()
******************************************************************************
* Summary:
* This function is used update baselines and decode gestures
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* This function updates baseline value for all the sensors after scanning is complete and 
* decodes gesture based on number of fingers
*
* Side Effects:
* numberOfFingers, prevnumberofFingers, gesture_code is updated
*
* Note: 
* Sequence of functions to be called by application for sucessful Trackpad Module scanning and 
* gesture decoding is as follows
* 1. Trackpad_Start_Poll()
* 2. Trackpad_IsComplete()
* 3. Trackpad_Poll()
*****************************************************************************/
void Trackpad_Poll(void)
{
#ifdef TRACKPAD_TEMPERATURE_VARIATION
    uint8 sensor_count, i;
#endif /* TRACKPAD_TEMPERATURE_VARIATION */
    while(CSD_Touchpad_IsBusy());             
    if(isScanInitiated)
    {
        isScanInitiated = false;
#ifndef DISABLE_TRACKPAD_SLEEP
        CSD_Touchpad_SaveConfig();
        CSD_Touchpad_Sleep();
#endif /* DISABLE_TRACKPAD_SLEEP */
        if(!isLowPowerMode)
        {
#ifdef TRACKPAD_TEMPERATURE_VARIATION
            sensor_count = 0x00;
            for (i = 0; i < CSD_Touchpad_TOTAL_SENSOR_COUNT; i++)
        	{
                if (CSD_Touchpad_sensorSignal[i] > TRACKPAD_TEMPERATURE_THRESHOLD)
                {
                    sensor_count++;
                }
        	}
            if (sensor_count >  TRACKPAD_TEMPERATURE_SENSORCOUNT)
        	{
#ifndef DISABLE_TRACKPAD_SLEEP
                CSD_Touchpad_Wakeup();
#endif /* DISABLE_TRACKPAD_SLEEP */
    			CSD_Touchpad_InitializeEnabledBaselines();
                CSD_Touchpad_ScanEnabledWidgets();
                while(CSD_Touchpad_IsBusy());
                CSD_Touchpad_UpdateEnabledBaselines();
#ifndef DISABLE_TRACKPAD_SLEEP
                CSD_Touchpad_SaveConfig();
                CSD_Touchpad_Sleep();
#endif /* DISABLE_TRACKPAD_SLEEP */
                return;
        	}
#endif /* TRACKPAD_TEMPERATURE_VARIATION */
            CSD_Touchpad_UpdateEnabledBaselines();
            prevnumberofFingers = numberOfFingers;
            numberOfFingers = CSD_Touchpad_GetDoubleTouchCentroidPos(fingerPosition);        
            gesture_code = CSD_Touchpad_DecodeAllGestures(numberOfFingers, fingerPosition);
            //Trackpad_Custom_Gesture_Detection(&gesture_code);
        
            //if (((numberOfFingers > 0) && (numberOfFingers != INVALID_FINGERS_DETECTED)) || (prevClickGesture) || \
            //                                                        (prevReportType != NO_REPORT) || (gesture_code != 0))
           // {
              //  DEVICE_POST_EVENT(TRACKPAD_EVENT);
            //}
            Debug_Print(DEBUG_MESSAGE_LEVEL_3,"trackpad numberOfFingers =%d\r\n",numberOfFingers);
            trackpad_gesture_code = handleEvents();
            if(trackpad_gesture_code)
            {
              DEVICE_POST_EVENT(TRACKPAD_EVENT);
            }
            if(trackpad_gesture_code)
            {
              trackpad_send_nocode = true;
            }
            //Debug_Print(DEBUG_MESSAGE_LEVEL_4,"trackpad gesture_code =%d\r\n",trackpad_gesture_code);
            Visual_Scop_Show(CSD_Touchpad_sensorSignal[0],CSD_Touchpad_sensorSignal[1],CSD_Touchpad_sensorSignal[3],CSD_Touchpad_sensorSignal[4]);
        }
        else
        {
            if(!isRowScan)
            {
                CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_COL1__TP);
                CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_COL3__TP);
                //CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_COL4__TP);
                //CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_COL5__TP);
                //CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_COL7__TP);
                
                if(CSD_Touchpad_CheckIsSensorActive(CSD_Touchpad_SENSOR_TRACKPAD_COL1__TP) || 
                    //CSD_Touchpad_CheckIsSensorActive(CSD_Touchpad_SENSOR_TRACKPAD_COL2__TP) || 
                    //CSD_Touchpad_CheckIsSensorActive(CSD_Touchpad_SENSOR_TRACKPAD_COL3__TP) || 
                    CSD_Touchpad_CheckIsSensorActive(CSD_Touchpad_SENSOR_TRACKPAD_COL3__TP))
                {
                    DEVICE_ACTIVITY_DETECTED();
                }
            }
            else
            {
                CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_ROW1__TP);
                CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_ROW3__TP);
                //CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_ROW4__TP);
                //CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_ROW5__TP);
                //CSD_Touchpad_UpdateSensorBaseline(CSD_Touchpad_SENSOR_TRACKPAD_ROW7__TP);
                
                if(CSD_Touchpad_CheckIsSensorActive(CSD_Touchpad_SENSOR_TRACKPAD_ROW1__TP) || 
                    //CSD_Touchpad_CheckIsSensorActive(CSD_Touchpad_SENSOR_TRACKPAD_ROW2__TP) || 
                    //CSD_Touchpad_CheckIsSensorActive(CSD_Touchpad_SENSOR_TRACKPAD_ROW5__TP) || 
                    CSD_Touchpad_CheckIsSensorActive(CSD_Touchpad_SENSOR_TRACKPAD_ROW3__TP))
                {
                    DEVICE_ACTIVITY_DETECTED();
                }
                isRowScan = !isRowScan;
            }
            numberOfFingers = 0;
        }
    }
}

/*****************************************************************************
* Function Name: Trackpad_Get_Report(Report *report)
******************************************************************************
* Summary:
* This function generates report for touch containing the delta in x, y, zwheel, mkey and kcode
*                 
* Parameters:
* Report *report - Pointer for report structure
*
* Return:
* Returns Report type based on detected gesture
*
* Theory:
* Based on the trackpad event appropriate event is generated and  report for touch containing 
* delta in x, y, zwheel, modifier key and key code
*
*
* Side Effects:
* prevReportType is updated
*
* Note:
* None
*****************************************************************************/
ReportType Trackpad_Get_Report(Report *report)
{
    ReportType reportType = NO_REPORT;
    ReportType tempreportType = prevReportType;
    if (DEVICE_GET_EVENT(TRACKPAD_EVENT))
    {
        //Debug_Print(DEBUG_MESSAGE_LEVEL_4,"trackpad_gesture_code = %d\r\n",trackpad_gesture_code);
        reportType |= Trackpad_Gesture_Map(report,trackpad_gesture_code);    
        if((reportType) & (KEYBOARD_REPORT | MULTIMEDA_REPORT | POWER_REPORT))
        {
            prevReportType = reportType;
        }
        else
        {
            prevReportType = NO_REPORT;    
        }
        reportType |= tempreportType; 
    }
    return reportType;
}

/*****************************************************************************
* Function Name: Trackpad_Set_State(Device_State state)
******************************************************************************
* Summary:
* This function sets state of trackpad module
*                 
* Parameters:
* Device_State state - state of the trackpad module
*
* Return:
* None
*
* Theory:
* 
*
*
* Side Effects:
* isLowPowerMode, isRowScan and gesture_code is updated
*
* Note:
* None
*****************************************************************************/
void Trackpad_Set_State(Device_State state)
{
    if(state == DEVICE_ACTIVE)
    {
        isLowPowerMode = false;
    }
    else
    {
        isRowScan = false;
        isLowPowerMode = true;
        gesture_code = 0;
    }
}

/*****************************************************************************
* Function Name: Trackpad_IsActive()
******************************************************************************
* Summary:
* This function returns user activity status on the trackpad
*                 
* Parameters:
* None
*
* Return:
* Returns status of trackpad activity
*
* Theory:
* Returns true if any finger is present on the trackpad
*
* Side Effects:
* None
*
* Note:
* None
*****************************************************************************/
bool Trackpad_IsActive(void)
{
    if (((numberOfFingers > 0) && (numberOfFingers != INVALID_FINGERS_DETECTED)) || prevClickGesture || prevReportType)
    {
        return true;
    }
    else
    {
        return false;
    }
}

/*****************************************************************************
* Function Name: Trackpad_Stop()
******************************************************************************
* Summary:
* This function stops trackkpad module scanning
*                 
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* Stops the CSD component
*
* Side Effects:
* None
*
* Note:
* None
*****************************************************************************/
void Trackpad_Stop(void)
{
    CSD_Touchpad_Stop();
}

#endif  /* DISABLE_TRACKPAD */
